package handler

import (
	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/service"
	"fitness/go-admin/pkg/response"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

type StatisticsHandler struct {
	service service.StatisticsService
}

func NewStatisticsHandler(service service.StatisticsService) *StatisticsHandler {
	return &StatisticsHandler{service: service}
}

// fillDateRangeFromPeriod 根据period参数填充日期范围
func fillDateRangeFromPeriod(req *model.StatisticsQueryReq) error {
	// 如果已经指定了开始和结束日期，则不处理period
	if req.StartDate != "" && req.EndDate != "" {
		return nil
	}

	// 如果没有period参数，返回错误
	if req.Period == "" {
		return nil
	}

	now := time.Now()
	var startDate, endDate time.Time

	switch req.Period {
	case "today":
		// 今天
		startDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
		endDate = startDate.Add(24 * time.Hour)
		if req.GroupBy == "" {
			req.GroupBy = "day"
		}
	case "week":
		// 最近7天
		endDate = now
		startDate = now.AddDate(0, 0, -7)
		if req.GroupBy == "" {
			req.GroupBy = "day"
		}
	case "month":
		// 当前月
		startDate = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
		endDate = startDate.AddDate(0, 1, 0)
		if req.GroupBy == "" {
			req.GroupBy = "day"
		}
	case "year":
		// 当前年
		startDate = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location())
		endDate = startDate.AddDate(1, 0, 0)
		if req.GroupBy == "" {
			req.GroupBy = "month"
		}
	default:
		// 默认最近30天
		endDate = now
		startDate = now.AddDate(0, 0, -30)
		if req.GroupBy == "" {
			req.GroupBy = "day"
		}
	}

	req.StartDate = startDate.Format("2006-01-02")
	req.EndDate = endDate.Format("2006-01-02")
	return nil
}

// ==================== 综合统计 ====================

// GetOverview 获取数据概览
func (h *StatisticsHandler) GetOverview(c *gin.Context) {
	date := c.DefaultQuery("date", "")

	overview, err := h.service.GetOverview(date)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, overview, "获取成功")
}

// GetTrends 获取趋势对比
func (h *StatisticsHandler) GetTrends(c *gin.Context) {
	var req model.TrendsQueryReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	trends, err := h.service.GetTrends(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, trends, "获取成功")
}

// ==================== 会员统计 ====================

// GetMemberGrowth 获取会员增长趋势
func (h *StatisticsHandler) GetMemberGrowth(c *gin.Context) {
	var req model.StatisticsQueryReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	// 根据period参数自动填充日期范围
	if err := fillDateRangeFromPeriod(&req); err != nil {
		response.Error(c, 400, err.Error())
		return
	}

	// 验证日期参数
	if req.StartDate == "" || req.EndDate == "" {
		response.Error(c, 400, "请提供period参数或start_date和end_date参数")
		return
	}

	growth, err := h.service.GetMemberGrowth(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, growth, "获取成功")
}

// GetMemberDistribution 获取会员分布
func (h *StatisticsHandler) GetMemberDistribution(c *gin.Context) {
	var req model.MemberDistributionReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	distribution, err := h.service.GetMemberDistribution(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, distribution, "获取成功")
}

// ==================== 课程统计 ====================

// GetCourseRanking 获取课程排行
func (h *StatisticsHandler) GetCourseRanking(c *gin.Context) {
	var req model.CourseRankingReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	ranking, err := h.service.GetCourseRanking(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, ranking, "获取成功")
}

// GetCourseBookingTrends 获取课程预约趋势
func (h *StatisticsHandler) GetCourseBookingTrends(c *gin.Context) {
	var courseID *uint
	if idStr := c.Query("course_id"); idStr != "" {
		id, err := strconv.ParseUint(idStr, 10, 32)
		if err == nil {
			uid := uint(id)
			courseID = &uid
		}
	}

	var req model.StatisticsQueryReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	// 根据period参数自动填充日期范围
	if err := fillDateRangeFromPeriod(&req); err != nil {
		response.Error(c, 400, err.Error())
		return
	}

	// 验证日期参数
	if req.StartDate == "" || req.EndDate == "" {
		response.Error(c, 400, "请提供period参数或start_date和end_date参数")
		return
	}

	trends, err := h.service.GetCourseBookingTrends(courseID, &req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, trends, "获取成功")
}

// GetTimeslotStats 获取时段分析
func (h *StatisticsHandler) GetTimeslotStats(c *gin.Context) {
	var req model.StatisticsQueryReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	// 根据period参数自动填充日期范围
	if err := fillDateRangeFromPeriod(&req); err != nil {
		response.Error(c, 400, err.Error())
		return
	}

	// 验证日期参数
	if req.StartDate == "" || req.EndDate == "" {
		response.Error(c, 400, "请提供period参数或start_date和end_date参数")
		return
	}

	stats, err := h.service.GetTimeslotStats(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, stats, "获取成功")
}

// ==================== 教练统计 ====================

// GetCoachWorkload 获取教练工作量
func (h *StatisticsHandler) GetCoachWorkload(c *gin.Context) {
	var req model.CoachWorkloadReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	workload, err := h.service.GetCoachWorkload(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, workload, "获取成功")
}

// GetCoachRanking 获取教练排行
func (h *StatisticsHandler) GetCoachRanking(c *gin.Context) {
	var req model.CourseRankingReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	ranking, err := h.service.GetCoachRanking(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, ranking, "获取成功")
}

// ==================== 营收统计 ====================

// GetRevenueOverview 获取营收总览
func (h *StatisticsHandler) GetRevenueOverview(c *gin.Context) {
	var req model.StatisticsQueryReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	// 根据period参数自动填充日期范围
	if err := fillDateRangeFromPeriod(&req); err != nil {
		response.Error(c, 400, err.Error())
		return
	}

	// 验证日期参数
	if req.StartDate == "" || req.EndDate == "" {
		response.Error(c, 400, "请提供period参数或start_date和end_date参数")
		return
	}

	overview, err := h.service.GetRevenueOverview(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, overview, "获取成功")
}

// GetRevenueTrends 获取营收趋势
func (h *StatisticsHandler) GetRevenueTrends(c *gin.Context) {
	var req model.RevenueQueryReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	// 根据period参数自动填充日期范围
	if req.Period != "" && (req.StartDate == "" || req.EndDate == "") {
		var baseReq model.StatisticsQueryReq
		baseReq.Period = req.Period
		baseReq.GroupBy = req.GroupBy
		if err := fillDateRangeFromPeriod(&baseReq); err != nil {
			response.Error(c, 400, err.Error())
			return
		}
		req.StartDate = baseReq.StartDate
		req.EndDate = baseReq.EndDate
		if req.GroupBy == "" {
			req.GroupBy = baseReq.GroupBy
		}
	}

	// 验证日期参数
	if req.StartDate == "" || req.EndDate == "" {
		response.Error(c, 400, "请提供period参数或start_date和end_date参数")
		return
	}

	trends, err := h.service.GetRevenueTrends(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, trends, "获取成功")
}

// GetConsumptionStats 获取消费统计
func (h *StatisticsHandler) GetConsumptionStats(c *gin.Context) {
	var req model.StatisticsQueryReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	// 根据period参数自动填充日期范围
	if err := fillDateRangeFromPeriod(&req); err != nil {
		response.Error(c, 400, err.Error())
		return
	}

	// 验证日期参数
	if req.StartDate == "" || req.EndDate == "" {
		response.Error(c, 400, "请提供period参数或start_date和end_date参数")
		return
	}

	var consumeType *string
	if typeStr := c.Query("consume_type"); typeStr != "" {
		consumeType = &typeStr
	}

	stats, err := h.service.GetConsumptionStats(&req, consumeType)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, stats, "获取成功")
}
